#!/usr/bin/env python
# encoding: utf-8


"""
@file: sanjiaohanshu.py
@time: 2017/2/23 上午11:45
"""
# 三角函数对象
from mathsolver.functions.base import *
from sympy import sin, cos
from mathsolver.functions.sanjiao.zhiyu import SanJiaoHanShuZhiYu
from mathsolver.functions.sanjiao import sanjiao_utils as su
from mathsolver.functions.sanjiao.dandiaoxing import SanJiaoDanDiaoQuJian
from mathsolver.functions.sanjiao.zhouqi import ZhouQi
from mathsolver.functions.sanjiao.huajian import trig_simplify


class SanJiaoHanShu(BaseFunction):
    def __init__(self, fx, expression, variable=None, x_interval=None):
        self.fx = fx
        self.expression = sympify(expression)
        if not variable:
            self.variable = list(sympify(self.expression).free_symbols)[0]
        if not x_interval:
            self.x_interval = S.Reals

    def simp(self):
        self.expression = trig_simplify(self.expression)

    def domain_of_def(self):
        """
        x 的定义域
        :return:
        """
        return self.x_interval

    def range(self):
        """
        f(x)的值域
        :return:
        """
        if self.domain_of_def() == S.Reals:
            return SanJiaoHanShuZhiYu(verbose=True).solver(BaseValue(self.expression)).output[0].interval
        else:
            return ''

    def cycle(self):
        """
        周期
        :return:
        """
        return ZhouQi(verbose=True).solver(self.expression).output[0].sympify()

    def extreme_point(self, point_type=None):
        """
        极值点。1 可能没有极值点; 2 只有极小值/极大值; 3 极小值和极大值都存在
        情况1 形如 y = A*sin(w*x + b)  + h
        :param point_type: 极值点类型。极大值或极小值。如果没有则都取
        :return:
        """
        if su.trig_is_simped(self.expression):
            trig_coef, trig_type, trig_arg, const = su.simpled_trig_info(self.expression)
            if point_type == 'max':
                pass
            elif point_type == 'min':
                pass
            elif not point_type:
                if trig_type in [sin, cos]:
                    point_x = solve(trig_arg - sympify('k*pi + pi/2'), sympify('x'))[0]
                    return point_x, (abs(trig_coef), -abs(trig_arg))
        else:
            return None

    def monotone_interval(self, intl_type_text):
        """
        单调区间
        :param intl_type_text: 单调类型。递增，递减
        :return:
        """

        if self.x_interval:
            return SanJiaoDanDiaoQuJian(verbose=True).solver(BaseEq([self.fx, self.expression]), self.x_interval,
                                                             intl_type_text)
        else:
            return SanJiaoDanDiaoQuJian(verbose=True).solver(BaseEq([self.fx, self.expression]), intl_type_text)

    def move(self, direct, step):
        """
        函数移动。左加右减，上加下减
        :param direct: 方向 left, right, up, down
        :param step: 单位
        :return:
        """
        if direct == 'left':
            self.expression = self.expression.subs(self.variable, self.variable + step)
        elif direct == 'right':
            self.expression = self.expression.subs(self.variable, self.variable + step)
        elif direct == 'up':
            self.expression = self.expression + step
        elif direct == 'down':
            self.expression = self.expression - step
        else:
            pass

    def monotony(self, m_type_text):
        """
        函数的单调性
        :param m_type_text: 单调类型(单增或者单减)
        :return:
        """
        if self.x_interval:
            return SanJiaoDanDiaoQuJian(verbose=True).solver(self.expression, self.x_interval, m_type_text)
        else:
            return SanJiaoDanDiaoQuJian(verbose=True).solver(self.expression, m_type_text)


if __name__ == '__main__':
    pass
